<!-- xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com -->
<template>
  <div class="column" @drop="_drop" @dragenter="_suppress" @dragover="_suppress">
    <div class="row">
      <div class="row">
        <div class="col-xs-12">
          <form class="form-inline">
            <div class="form-group">
              <div class="wrapper">
                <input
                  type="file"
                  class="form-control"
                  id="file"
                  :accept="SheetJSFT"
                  @change="_change"
                />
                <span>请上传Execl文件</span>
              </div>
            </div>
          </form>
        </div>
      </div>
      <div class="row">
        <div class="col-xs-12">
          <a-button :disabled="data.length ? false : true" class="btn btn-success" @click="_export">
            导出execl
          </a-button>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-12">
        <div class="table-responsive">
          <table class="table table-striped">
            <thead>
              <tr>
                <th v-for="c in cols" :key="c.key">{{ c.name }}</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(r, key) in data" :key="key">
                <td v-for="c in cols" :key="c.key">{{ r[c.key] }}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang='ts'>
import XLSX from 'xlsx';
import Vue from 'vue';
import Component from 'vue-class-component';

const make_cols = (refstr: any) =>
  Array(XLSX.utils.decode_range(refstr).e.c + 1)
    .fill(0)
    .map((x, i) => ({ name: XLSX.utils.encode_col(i), key: i }));

const _SheetJSFT = [
  'xlsx',
  'xlsb',
  'xlsm',
  'xls',
  'xml',
  'csv',
  'txt',
  'ods',
  'fods',
  'uos',
  'sylk',
  'dif',
  'dbf',
  'prn',
  'qpw',
  '123',
  'wb*',
  'wq*',
  'html',
  'htm',
]
  .map(function (x) {
    return '.' + x;
  })
  .join(',');

@Component({
  components: {},
})
export default class Execl extends Vue {
  private data: any = ['SheetJS'.split(''), '1234567'.split('')];
  private cols: any = [
    { name: 'A', key: 0 },
    { name: 'B', key: 1 },
    { name: 'C', key: 2 },
    { name: 'D', key: 3 },
    { name: 'E', key: 4 },
    { name: 'F', key: 5 },
    { name: 'G', key: 6 },
  ];
  private SheetJSFT: any = _SheetJSFT;

  public _suppress(evt: any) {
    evt.stopPropagation();
    evt.preventDefault();
  }
  public _drop(evt: any) {
    evt.stopPropagation();
    evt.preventDefault();
    const files = evt.dataTransfer.files;
    if (files && files[0]) this._file(files[0]);
  }
  public _change(evt: any) {
    const files = evt.target.files;
    if (files && files[0]) this._file(files[0]);
  }
  public _export(evt: any) {
    /* convert state to workbook */
    const ws = XLSX.utils.aoa_to_sheet(this.data);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'SheetJS');
    /* generate file and send to client */
    XLSX.writeFile(wb, 'sheetjs.xlsx');
  }
  public _file(file: any) {
    /* Boilerplate to set up FileReader */
    const reader = new FileReader();
    reader.onload = (e: any) => {
      /* Parse data */
      const bstr = e.target.result;
      const wb = XLSX.read(bstr, { type: 'binary' });
      /* Get first worksheet */
      const wsname = wb.SheetNames[0];
      const ws = wb.Sheets[wsname];
      /* Convert array of arrays */
      const data = XLSX.utils.sheet_to_json(ws, { header: 1 });
      /* Update state */
      this.data = data;
      this.cols = make_cols(ws['!ref']);
    };
    reader.readAsBinaryString(file);
  }
}
</script>
<style lang="less" scoped>
.column {
  & > .row {
    margin: 20px;
    width: calc(100% - 40px);
    .wrapper {
      width: 100%;
      height: 200px;
      border: 1px dashed #ccc;
      margin-bottom: 20px;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      input {
        width: 100%;
        height: 100%;
        opacity: 0;
        z-index: 9;
        position: absolute;
      }
    }
    label {
      width: 200px;
      display: block;
      height: 40px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
}
/* Table Head */
.table {
  width: 100%;
} /* Border styles */
.table thead,
.table tr {
  border-top-width: 1px;
  border-top-style: solid;
  border-top-color: rgb(230, 189, 189);
}
.table {
  border-bottom-width: 1px;
  border-bottom-style: solid;
  border-bottom-color: rgb(230, 189, 189);
}

/* Padding and font style */
.table td,
.table th {
  padding: 5px 10px;
  font-size: 12px;
  font-family: Verdana;
  color: rgb(177, 106, 104);
}

/* Alternating background colors */
.table tr:nth-child(even) {
  background: rgb(238, 211, 210);
}
.table tr:nth-child(odd) {
  background: #fff;
}
</style>